package com.example.kingdee.kingdeeBridge.kingdeeImpl.impl;

import com.example.kingdee.common.StringUtils;
import com.example.kingdee.common.constant.YiTiConstant;
import com.example.kingdee.exception.ProcedureException;
import com.example.kingdee.kingdeeBridge.common.RequestResult;
import com.example.kingdee.kingdeeBridge.dto.BillWriteInDto;
import com.example.kingdee.kingdeeBridge.dto.PushDto;
import com.example.kingdee.kingdeeBridge.entity.SrcBillEntry;
import com.example.kingdee.kingdeeBridge.kingdeeAbs.FolderKingdee;
import com.example.kingdee.kingdeeBridge.kingdeeImpl.BillImpl;
import com.example.kingdee.mapper.TBxStMapper;
import com.example.kingdee.sqlTool.SqlTool;
import com.example.kingdee.sqlTool.common.DataObject;
import com.example.kingdee.sqlTool.common.QueryObject;
import com.example.kingdee.sqlTool.sqltoolEnum.FormIdEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;

import java.util.*;

/**
 * 采购订单接口实现类
 */
@Service
public class PurOrderImpl implements BillImpl {

    @Autowired
    private SqlTool sqlTool;

    @Autowired
    private TBxStMapper tBxStMapper;

    @Autowired
    private ReceiveNoticeImpl receiveNotice;
    /**
     *
     * @param fid 表id
     * @return
     */
    @Override
    public Map<String, String> selectTargetBillEntry(String fid) {
        //查询收料通知单
        QueryObject inventorySelect = new QueryObject(FormIdEnum.purReceiveBill);
        ArrayList<String> resultKeyArray = new ArrayList<>();
        inventorySelect.addSelect("FDetailEntity_FEntryID");//明细行id
        resultKeyArray.add("entryId");
        inventorySelect.addSelect("FSrcEntryId");//原单分录内码
        resultKeyArray.add("srcEntryId");
        inventorySelect.addCondition("fid", fid);
        ArrayList<HashMap<String, Object>> targetEntryInfo = sqlTool.weaveResult(inventorySelect, resultKeyArray);
        //构建收料通知单明细行id和原单行id对应关系
        Map<String, String> keyValue = new HashMap<>();
        for (HashMap<String, Object> sld : targetEntryInfo) {
            keyValue.put(sld.get("srcEntryId").toString(), sld.get("entryId").toString());
        }
        return keyValue;
    }

    /**
     *
     * @param fid 表id
     * @param billWriteInDto 源单信息
     * @param targetInfo 目标单据行id和源单行id对应关系
     * @return
     */
    @Override
    public RequestResult updateTargetBillEntry(String fid, BillWriteInDto billWriteInDto, Map<String, String> targetInfo) {
        List<SrcBillEntry> srcBillEntryList = billWriteInDto.getSrcBillEntryList();
        //将源单明细按照行id进行分类
        MultiValueMap<String, SrcBillEntry> classFySrcBillEntry = sqlTool.getClassFy(srcBillEntryList);
        //修改收料数量，仓库
        List<Map<String, Object>> detailEntityList = new ArrayList<>();
        for (String srcEntryId : classFySrcBillEntry.keySet()) {
            List<SrcBillEntry> srcBillEntries = classFySrcBillEntry.get(srcEntryId);
            for (int i = 0; i < srcBillEntries.size(); i++) {
                SrcBillEntry srcBillEntry = srcBillEntries.get(i);
                Map<String,Object> detailEntity = new LinkedHashMap<>();
                if (i == 0){
                    //修改下推的行
                    detailEntity.put("FEntryID", targetInfo.get(srcEntryId));//行id 必填
                }else {
                    //查询采购订单原单信息
                    Map<String, Object> srcPoorInfo = tBxStMapper.getSrcPoorInfo(srcEntryId);

                    //构建基础信息
                    detailEntity.put("FEntryID", 0);//行id 必填
                    detailEntity.put("FSrcEntryId", srcEntryId);//源单分录内码 必填
                    HashMap<String, Object> materialId = new HashMap<>();
                    materialId.put("fnumber", srcPoorInfo.get("itemNumber"));
                    HashMap<String, Object> unitNumber = new HashMap<>();
                    unitNumber.put("fnumber", srcPoorInfo.get("unitNumber"));
                    detailEntity.put("FMaterialId", materialId);//物料id 必填
                    detailEntity.put("fTaxPrice", srcPoorInfo.get("taxPrice"));//含税单价 必填
                    detailEntity.put("FUnitId", unitNumber);//收料单位 必填
                    detailEntity.put("FSrcId", srcPoorInfo.get("poorId"));//源单内码 必填
                    detailEntity.put("FSrcBillNo", srcPoorInfo.get("poorBillNo"));//源单编号 必填
                    detailEntity.put("FSrcFormId", "PUR_PurchaseOrder");//源单类型 必填
                    detailEntity.put("FOrderBillNo", srcPoorInfo.get("poorBillNo"));//订单单号
                    detailEntity.put("FACCRATE", 100);//验收比例
                    detailEntity.put("FPOQTY", srcPoorInfo.get("FQTY"));//订单数量

                    //构建原单关联关系
                    List<Map<String, Object>> detailLinkList = new ArrayList<>();
                    HashMap<String, Object> detailLink = new HashMap<>();
                    detailLink.put("FDetailEntity_Link_FFlowId", "");//业务流程图
                    detailLink.put("FDetailEntity_Link_FFlowLineId", "");//推进路线
                    detailLink.put("FDetailEntity_Link_FRuleId", YiTiConstant.PUR_PURCHASE_ORDER_PUR_RECEIVE_BILL);//转换规则
                    detailLink.put("FDetailEntity_Link_FSTableId", 0);//源单表内码
                    detailLink.put("FDetailEntity_Link_FSTableName", "t_PUR_POOrderEntry");//源单表
                    detailLink.put("FDetailEntity_Link_FSBillId", srcPoorInfo.get("poorId"));//源单内码
                    detailLink.put("FDetailEntity_Link_FSId", srcEntryId);//源单分录内码
                    detailLinkList.add(detailLink);
                    detailEntity.put("FDetailEntity_Link", detailLinkList);//源单关联关系 必填
                }
                detailEntity.put("FActReceiveQty", srcBillEntry.getQty());//交货数量
                detailEntity.put("FSUPDELQTY", srcBillEntry.getQty());//供应商交货数量 (必填项)
                detailEntity.put("F_QNSD_TEXT", srcBillEntry.getReserved1());//送货单明细行id
                if(!StringUtils.isEmpty(srcBillEntry.getStockNumber())){
                    HashMap<String, Object> stockId = new HashMap<>();
                    stockId.put("fnumber", srcBillEntry.getStockNumber());
                    detailEntity.put("FStockId", stockId);//仓库 必填
                }
                if (!StringUtils.isEmpty(srcBillEntry.getStockLocNumber())){
                    String stockLocFlexNumber = sqlTool.getStockLocFlexNumber(srcBillEntry.getStockLocNumber(), srcBillEntry.getStockNumber());
                    //仓位
                    Map<String, Object> shippingSpaceNumber = new HashMap<>(); //位置仓位值编码 必填
                    shippingSpaceNumber.put("FNumber", srcBillEntry.getStockLocNumber());
                    Map<String, Object> stockLocId = new HashMap<>();
                    stockLocId.put("FSTOCKLOCID__" + stockLocFlexNumber, shippingSpaceNumber);
                    detailEntity.put("FStockLocId", stockLocId);
                }
                detailEntityList.add(detailEntity);
            }
        }
        //修改收料通知单
        DataObject order = new DataObject(FormIdEnum.purReceiveBill);
        order.setAttribute("FID", fid);
        order.setAttribute("FSendBillNo", billWriteInDto.getReserved1());
        order.setAttribute("FIsMobile", false);//是否来自移动
        order.setAttribute("FACCTYPE", "Q");//验收方式
        order.setAttribute("FDetailEntity", detailEntityList);//订单明细
        try {
            Map<String, Object> result = sqlTool.editForDataObject(order);
            if (result.get("code").toString().equals("200")){
                return RequestResult.ofSuccess(result);
            }else {
                return RequestResult.ofError(result.get("msg").toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ProcedureException("无法调用云星空接口");
        }
    }

    /**
     *  免检的物料直接下推采购入库，插入待检标打印记录
     * @param billNo 单据编号
     */
    @Override
    public void postPosition(String billNo) {
        //查询收料通知单免检物料的信息
        List<Map<String, Object>> entryIdList = tBxStMapper.selectReceiveInfoByBill(billNo);
        if (entryIdList != null && entryIdList.size() != 0){
            //数据筛选
            List<SrcBillEntry> srcBillEntryList = new ArrayList<>();
            for (Map<String, Object> entry : entryIdList) {
                String itemType = entry.get("itemType").toString();
                String entryId = entry.get("entryId").toString();
                Object postEntryId = entry.get("postEntryId");
                //筛选出免检物料
                if (itemType.equals("0")){
                    //免检物料
                    SrcBillEntry srcBillEntry = new SrcBillEntry();
                    srcBillEntry.setEntryId(entryId);
                    srcBillEntryList.add(srcBillEntry);
                }else {
                    //插入待检标签
                    tBxStMapper.insertPrintInfo(entryId, "采购收料", "A01");
                }
                //反写送货单上的送料单id
                tBxStMapper.updatePostInfo(entryId, postEntryId);
            }

            //下推采购入库
            if (srcBillEntryList.size() !=0 ){
                //填充源单和目标单表单id
                PushDto pushDto = new PushDto();
                pushDto.setSrcFormId(FormIdEnum.purReceiveBill);
                pushDto.setTargetFormId(FormIdEnum.stkInStock);
                //组合实现类和抽象类
                FolderKingdee folderKingdee = new FolderKingdee(receiveNotice);
                //按明细行id进行下推
                folderKingdee.addPushDtoEntryIds(pushDto, srcBillEntryList);
                //进行单据下推
                RequestResult pushDownResult = folderKingdee.pushDown(pushDto);
                //下推失败则提示错误信息
                if (pushDownResult.getCode().equals("500")){
                    folderKingdee.deleteTargetBill(pushDownResult.getId());
                    throw new ProcedureException(pushDownResult.getMsg());
                }
                //提交审核订单
                folderKingdee.auditTargetBill(pushDownResult.getNumber());
            }
        }
    }

    /**
     *
     * @param billNo 单据编号
     */
    @Override
    public void auditTargetBill(String billNo) {
        //提交审核
        sqlTool.auditBill(billNo, FormIdEnum.purReceiveBill);
    }

    /**
     * @param fid 单据id
     */
    @Override
    public void deleteTargetBill(String fid) {
        sqlTool.deleteBill(fid, FormIdEnum.purReceiveBill);
    }


}
